/*
 * Character.cpp
 *
 *  Created on: Oct 8, 2011
 *  Created by: Devin Manno
 *  Updated by: Devin Manno,
 *	Last Update: Oct 14, 2011
 */
#include "Character.h"
#include <stdexcept>

Character::Character(string playerName, CharClass cClass, std::string objectType) : equipment(EquipmentType::maxSlots), Base(objectType) {  //initialize fixed size and NULL values
	setDesc(playerName);

	dead = false;				// character was just created, it's not dead yet!
	characterClass = cClass;
	AttackType attack0("Melee", 50, 0);	// add basic attack for all Characters (swing weapon)
	unlockedAttacks.push_back(true);	// sets attack 0 to true meaning it is unlocked
	attacks.push_back(attack0);		// add basic attack to attacks vector
}

Character::~Character() {
	// TODO Auto-generated destructor stub
}

// getters
/*
 * getNumAttacks
 * Description: gets the number of attacks the character can choose from
 * Pre: none
 * Post: none
 * Returns: the number of attack abilities the character has
 */
int Character::getNumAttacks() const{

	unsigned int count = 0;
	for(unsigned int i = 0; i< unlockedAttacks.size(); i++){
		if(unlockedAttacks[i])
			count++;
	}
	return count;
}


bool Character::getAttackType(int attackIndex, AttackType& attack)
{
	try {
		attack = attacks.at(attackIndex);
	}
	catch( out_of_range& e ) {
		return false;
	}

	return true;
}

/*
 * isDead
 * Description: checks to see if the player is dead
 * Pre: none
 * Post: none
 * Returns: true if the player is dead, false otherwise
 */
bool Character::isDead() const{
	return dead;
}

/*
 * getEquipment
 * Description: access to the character's equipment slots for GUI and controller classes.
 * Pre: none
 * Post: none
 * Returns: a const ref (read-only) to character's equipment
 */

const vector<EquipmentType*>& Character::getEquipment() const{
	return equipment;
}

CharClass Character::getCharClass() const{
	return characterClass;
}

const vector<AttackType> Character::getAttacks(){
	vector<AttackType> atk;
	for(int i = 0; i < unlockedAttacks.size();i++){
		if(unlockedAttacks[i])
			atk.push_back(attacks[i]);
	}
	return atk;
}

// setters


/*
 * setDead
 * Description: Set's the player's death flag
 * Pre: deadStatus is true if the player is dead, false otherwise
 * Post: Character's dead flag is set to deadStatus
 * Returns: none
 */
void Character::setDead(bool deadStatus){
	dead = deadStatus;
}

/*
 * addAttack
 * Description: Adds an attack to the Characters
 * Pre: deadStatus is true if the player is dead, false otherwise
 * Post: Character's dead flag is set to deadStatus
 * Returns: none
 */
void Character::addAttack(const AttackType& attack){
	attacks.push_back(attack);	// add new attack to attacks vector
	unlockedAttacks.push_back(true);	// set new attack to unlocked
}

// virtual function implementations
std::string Character::getClassName()const{
	return "Character";
}

void Character::unlockAttack(int index){
	unlockedAttacks[index] = true;
}

void Character::loadCharacter(istream& in, Character& c)
{
    int i = 0, eListSize = 0, aListSize = 0;
    AttackType a;
    EquipmentType e;
    bool lock;
    char *tk = NULL;// pointers to chars
    char data[MAX] = ""; //to hold line
    in.getline(data,MAX - 1, '\n');
    tk = strtok(data, DELIMS); // get next token
    c.setObjectID(atoi(tk));
    tk = strtok(NULL, DELIMS); // get next token
    c.setDesc(tk);
    tk = strtok(NULL, DELIMS); // get next token
    c.setObjectType(tk);
    tk = strtok(NULL, DELIMS); // get next token
    switch(atoi(tk))
    {
        case 0:
            c.characterClass = WARRIOR;
            break;
        case 1:
            c.characterClass = WIZARD;
            break;
        case 2:
            c.characterClass = RANGER;
            break;
    }
    tk = strtok(NULL, DELIMS); // get next token
    c.dead = atoi(tk);
    tk = strtok(NULL, DELIMS); // get next token
    aListSize = atoi(tk);
    tk = strtok(NULL, DELIMS); // get next token
    eListSize = atoi(tk);
    for(i = 0; i < aListSize; ++i)
    {
        in >> a;
        c.attacks.push_back(a);
    }
    for(i = 0; i < aListSize; ++i)
    {
        in >> lock;
        c.unlockedAttacks.push_back(lock);
    }
    for(i = 0; i < eListSize; ++i)
    {
        in >> e;
        c.equipment.push_back(&e);
    }
	//c.inventory.loadInventory(in);
}

void Character::saveCharacter(ostream& out, Character& c)
{
    int i = 0;
    out << c.getObjectID() << ',' << c.getDesc() << ',' << c.getObjectType() << ',' << c.characterClass << ',' << c.dead << endl
        << c.attacks.size() << ',' << c.equipment.size() << endl;
    for(i = 0; i < c.attacks.size(); ++i)
    {
        out << c.attacks.at(i) << endl;
    }
    for(i = 0; i < c.attacks.size(); ++i)
    {
        out << c.unlockedAttacks.at(i) << endl;
    }
    for(i = 0; i < c.equipment.size(); ++i)
    {
        out << c.equipment.at(i) << endl;
    }
	//c.inventory.saveInventory(out);
}
